#include "../../include/lua/Config.h"
#include <stdlib.h>
#include <string.h>
#include <map>

namespace ZY {

    map< string , Config* > Config::_configMap;
    map< int , Config* > Config::_configIntMap;



    Config::Config(string file)
    {
        c_link = new Lua( file );
        m_filename.assign( file );
    }

    Config::~Config()
    {
        delete c_link;
    }

    vector<string>& Config::Call_config_func( const string func, string str[], int arg_num, int ret_num )
    {
        c_link->lua_set_ret( ret_num );
        c_link->lua_call_fun( func, str, arg_num );
        return c_link->lua_return_value();
    }

    vector<string>& Config::Get_config_list( const string t_name )
    {
        c_link->lua_get_tablevalue( t_name );
        return c_link->lua_return_value();
    }

    vector<string>& Config::Get_config_list( const string t_name, const string index_str )
    {
        c_link->lua_get_tablevalue( t_name, index_str );
        return c_link->lua_return_value();
    }

    float Config::Get_config_float( const string t_name, const string index_str )
    {
        vector<string>::iterator iter;
        c_link->lua_get_tablevalue( t_name, index_str );
        vector<string> tmp = c_link->lua_return_value( );
        for( iter = tmp.begin(); iter != tmp.end(); iter++ ){
            return atof( ( *iter).c_str() );
        }
        return -1.0;
    }
    float Config::Get_config_float( const string t_name, const int order )
    {
        vector<string>::iterator iter;
        c_link->lua_get_tablevalue( t_name, order );
        vector<string> tmp = c_link->lua_return_value( );
        for( iter = tmp.begin(); iter != tmp.end(); iter++ ){
            return atof( ( *iter).c_str() );
        }
        return -1.0;
    }

    int Config::Get_config_int( const string t_name, const string index_str )
    {
        vector<string>::iterator iter;
        c_link->lua_get_tablevalue( t_name, index_str );
        vector<string> tmp = c_link->lua_return_value( );
        for( iter = tmp.begin(); iter != tmp.end(); iter++ ){
            return atoi( ( *iter).c_str() );
        }
        return -1;
    }
    int Config::Get_config_int( const string t_name, const int order )
    {
        vector<string>::iterator iter;
        c_link->lua_get_tablevalue( t_name, order );
        vector<string> tmp = c_link->lua_return_value( );
        for( iter = tmp.begin(); iter != tmp.end(); iter++ ){
            return atoi( ( *iter).c_str() );
        }
        return -1;
    }

    string Config::Get_config_string( const string t_name, const string index_str )
    {
        string r_value = "";
        vector<string>::iterator iter;
        c_link->lua_get_tablevalue( t_name, index_str );
        vector<string> tmp = c_link->lua_return_value( );
        for( iter = tmp.begin(); iter != tmp.end(); iter++ ){
            return *iter;
        }
        return r_value;
    }
    string Config::Get_config_string( const string t_name, const int order )
    {
        string r_value = "";
        vector<string>::iterator iter;
        c_link->lua_get_tablevalue( t_name, order );
        vector<string> tmp = c_link->lua_return_value( );
        for( iter = tmp.begin(); iter != tmp.end(); iter++ ){
            return *iter;
        }
        return r_value;
    }

    void Config::Set_config( const string t_name, const string index_str, string value )
    {
        c_link->lua_set_tablevalue( t_name, index_str, value );
    }
    void Config::Set_config( const string t_name, const string index_str, int value )
    {
        char tmp[10];
        bzero( tmp, sizeof( tmp ) );
        sprintf( tmp, "%d", value );
        c_link->lua_set_tablevalue( t_name, index_str, tmp );
    }
    void Config::Set_config( const string t_name, const string index_str, float value )
    {
        char tmp[10];
        bzero( tmp, sizeof( tmp ) );
        sprintf( tmp, "%f", value );
        c_link->lua_set_tablevalue( t_name, index_str, tmp );
    }
    void Config::Set_config( const string t_name, const int order, string value )
    {
        c_link->lua_set_tablevalue( t_name, order, value );
    }
    void Config::Set_config( const string t_name, const int order, int value )
    {
        char tmp[10];
        bzero( tmp, sizeof( tmp ) );
        sprintf( tmp, "%d", value );
        c_link->lua_set_tablevalue( t_name, order, tmp );
    }
    void Config::Set_config( const string t_name, const int order, float value )
    {
        char tmp[10];
        bzero( tmp, sizeof( tmp ) );
        sprintf( tmp, "%f", value );
        c_link->lua_set_tablevalue( t_name, order, tmp );
    }
    void Config::Set_config( const string t_name, float value )
    {
        char tmp[10];
        bzero( tmp, sizeof( tmp ) );
        sprintf( tmp, "%f", value );
        c_link->lua_set_tablevalue( t_name, tmp );
    }
    void Config::Set_config( const string t_name, int value )
    {
        char tmp[10];
        bzero( tmp, sizeof( tmp ) );
        sprintf( tmp, "%d", value );
        c_link->lua_set_tablevalue( t_name, tmp );
    }
    void Config::Set_config( const string t_name, string value )
    {
        c_link->lua_set_tablevalue( t_name,  value );
    }

    void Config::Save_config( const string file_name, const string t_name )
    {
        c_link->lua_save_tablevalue( file_name, t_name );
    }

    void Config::Renew_config( const string file_name )
    {
        if( c_link ){
                delete c_link;
        }
        c_link = new Lua( file_name );
    }

    //void Config::close_config()
    //{
    //    delete c_link;
    //}
    Config & Config::getInstance( char *c ) {
        string str( c , strlen( c ) );
        return getInstance( str );
    }

    Config & Config::getInstance( string & filename )
    {
        if ( _configMap.count( filename ) == 0 ) {
            _configMap[filename] = new Config( filename );
        }
        return *_configMap[filename];
    }

    Config & Config::getInstance( int id )
    {

        if ( _configIntMap.count( id ) == 0 ) {
            _configIntMap[ id ] = new Config();
        }
        return *_configIntMap[id];
    }

    void Config::destroyInstance( const string & filename )
    {
        if ( _configMap.count( filename ) > 0 ) {
            delete _configMap[filename] ;
            _configMap.erase( filename );
        }
    }

    void Config::destroyInstance( int id )
    {
        if ( _configIntMap.count( id ) > 0 ) {
            delete _configIntMap[id] ;
            _configIntMap.erase( id );
        }
    }

    void Config::Open_config( const string file_name )
    {
        if ( c_link ) {
            delete c_link;
        }
        c_link = new Lua( file_name );
    }

    void Config::destroyInstance( Config & conf )
    {
        destroyInstance( conf.getFilename() );
    }
};
